package com.zmn.oms.dubbo.impl.zmn.normal.order;

import com.alibaba.fastjson.JSON;
import com.zmn.base.engineer.common.dro.foreign.engineer.ForeignEngineerDetailInfoDRO;
import com.zmn.base.engineer.dubbo.interfaces.foreign.EngineerListRemoteService;
import com.zmn.oms.business.interfaces.apply.CancelApplyBService;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.model.bo.work.apply.cancel.CancelApplyResultBO;
import com.zmn.oms.model.entity.omstrack.OrderWorkTrack;
import com.zmn.oms.model.entity.visit.OrderVisit;
import com.zmn.oms.services.interfaces.visit.OrderVisitService;
import org.apache.dubbo.config.annotation.Reference;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.business.interfaces.track.OrderTrackBService;
import com.zmn.oms.business.interfaces.work.OrderWorkListBService;
import com.zmn.oms.business.interfaces.worktrack.WorkTrackBService;
import com.zmn.oms.dubbo.dto.zmn.order.OrderWorkDetailSpoolDRO;
import com.zmn.oms.dubbo.dto.zmn.order.OrderWorkSpoolDRO;
import com.zmn.oms.dubbo.interfaces.zmn.normal.order.ZsNormalOrderNodeSpoolRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.entity.comment.OrderComment;
import com.zmn.oms.model.entity.comment.OrderCommentDetail;
import com.zmn.oms.model.entity.log.OrderLog;
import com.zmn.oms.model.entity.warranty.OrderWarranty;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.entity.work.OrderWorkQuery;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.oms.services.interfaces.comment.OrderCommentService;
import com.zmn.oms.services.interfaces.track.OrderTrackService;
import com.zmn.oms.services.interfaces.warranty.OrderWarrantyService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.services.interfaces.worktrack.WorkTrackService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述： 订单生命周期 节点
 *
 * @author yule
 * @date 2020/8/20 23:39
 */
@Slf4j
@Service(loadbalance = "roundrobin", timeout = 20000, retries = 2, version = DubboConsts.INTERFACE_VERSION, validation = "false")
public class ZsNormalOrderNodeSpoolRemoteServiceImpl implements ZsNormalOrderNodeSpoolRemoteService {

    @Autowired
    OrderWorkService orderWorkService;
    @Autowired
    OrderLogBService orderLogBService;
    @Autowired
    OrderWorkListBService orderWorkListBService;
    @Autowired
    OrderTrackBService orderTrackBService;
    @Autowired
    OrderTrackService orderTrackService;
    @Autowired
    OrderWarrantyService orderWarrantyService;
    @Autowired
    OrderCommentService orderCommentService;
    @Autowired
    WorkTrackService workTrackService;
    @Autowired
    WorkTrackBService workTrackBService;
    @Autowired
    OrderVisitService orderVisitService;
    @Autowired
    CancelApplyBService cancelApplyBService;

    @Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    EngineerListRemoteService engineerListRemoteService;


    @Override
    public ResponseDTO<List<OrderWorkDetailSpoolDRO>> listOrderNodeSpoolById(@NotNull Long workId, @NotNull Long orderId) {

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (Objects.isNull(orderWork)) {
            return ResponseDTO.fail("订单不存在");
        }

        List<OrderWorkDetailSpoolDRO> list = listOrderNodeSpoolList(orderWork, workId, orderId);
        return ResponseDTO.success(list);
    }


    private List<OrderWorkDetailSpoolDRO> listOrderNodeSpoolList(OrderWork orderWork, Long workId, Long orderId) {

        List<OrderWorkDetailSpoolDRO> detailOrderList = Lists.newArrayList();
        List<OrderLog> orderLogsByTypes = orderLogBService.findOrderLogsAscByTypes(orderId, OrderNodeSpoolConsts.types);
        if (CollectionUtils.isEmpty(orderLogsByTypes)) {
            return detailOrderList;
        }

        // 1.非计价器订单 2.计价器订单
        Integer servItemType = orderWork.getServItemType();
        // 订单已完成 组装保修卡和评价节点
        boolean isComplete = orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_COMPLETE;
        // 保修卡
        OrderWarranty orderWarranty = orderWarrantyService.findByOrderId(orderId);
        // 存在保修卡
        boolean isExistWarranty = isComplete && Objects.nonNull(orderWarranty);

        // 订单节点转换
        List<OrderWorkDetailSpoolDRO> finalContactList = new ArrayList<>();
        List<OrderWorkDetailSpoolDRO> contactList = finalContactList;
        orderLogsByTypes.forEach(item -> {
            OrderWorkDetailSpoolDRO detail = new OrderWorkDetailSpoolDRO();
            detail.setOrderId(orderWork.getOrderId());
            detail.setWorkId(orderWork.getWorkId());
            detail.setOperateTime(item.getCreateTime());
            detail.setMasterId(item.getMasterId());

            ForeignEngineerDetailInfoDRO masterInfo = getMaterInfo(item.getMasterId());
            String masterName = "工程师";
            String masterPhone = null;
            if (Objects.nonNull(masterInfo)) {
                masterName = masterInfo.getRealName();
                if (StringUtils.isNotBlank(masterName)) {
                    masterName = masterName.substring(0, 1) + "工";
                }
                masterPhone = masterInfo.getMobile();
            }

            detail.setMasterPhone(masterPhone);
            detail.setMasterName(masterName);
            detail.setLogType(item.getType());
            detail.setLogTypeName(OrderNodeSpoolConsts.getOperateTypeName(item.getType()));
            detail.setLogRemark(OrderNodeSpoolConsts.getOperateTypeRemark(item.getType(), masterName, masterPhone, item.getMasterId(), servItemType, isExistWarranty, item.getContent()));
            finalContactList.add(detail);
        });

        // 是否存在多次上门操作
        boolean isMultipleVisit = contactList.stream().anyMatch(item -> item.getLogType().equals(OrderLogConsts.ORDER_LOG_TYPE_APPLY_MULTIPLE_VISIT));
        if (isMultipleVisit) {
            contactList = this.handleMultipleVisitNode(contactList, orderWork);
        }

        // 是否有过派单操作
        boolean isExistDistribute = contactList.stream().anyMatch(item -> item.getLogType().equals(OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE));

        // 是否是先付款
        boolean hasPrepay = NumberUtil.isNotNullOrZero(orderWork.getPrepayAmount());
        boolean prepaying = Objects.equals(orderWork.getPrepayStatus(), PayConsts.PAY_STATUS_ING);
        if (prepaying) {
            contactList.get(0).setLogRemark("提交成功，请主人尽快完成支付");
        } else {
            if (hasPrepay && !Objects.equals(orderWork.getPrepayStatus(), PayConsts.PAY_STATUS_ING) && orderWork.getPrepayTime() != null) {
                OrderWorkDetailSpoolDRO orderWorkDetailSpool = new OrderWorkDetailSpoolDRO();
                orderWorkDetailSpool.setOperateTime(orderWork.getPrepayTime());
                orderWorkDetailSpool.setLogType(OrderLogConsts.ORDER_LOG_TYPE_PAY);
                orderWorkDetailSpool.setLogTypeName("订单已支付");
                if (isExistDistribute) {
                    orderWorkDetailSpool.setLogRemark("支付成功，小啄将督促工程师尽快接单");
                } else {
                    orderWorkDetailSpool.setLogRemark("支付成功，将尽快为主人派单");
                }
                contactList.add(1, orderWorkDetailSpool);
            }
        }

        /// 处理第一个节点派单
        if (isExistDistribute) {
            String masterName = "工程师";
            if (contactList.size() > 1) {
                List<OrderWorkDetailSpoolDRO> tempList = contactList.stream().filter(item -> Objects.equals(item.getLogType(), OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE)).collect(Collectors.toList());
                if (tempList.size() > 0) {
                    masterName = tempList.get(0).getMasterName();
                }
            }
            contactList.get(0).setLogRemark("订单交给" + masterName + "，小啄将督促工程师尽快接单");
            // 处理节点合并
            contactList = handleNode(contactList, workId, orderId, orderWork);
        } else {

            // 处理退款重复日志节点
            handleRepeatNode(contactList);
            contactList = contactList.stream().filter(item -> !Objects.equals(item.getLogType(), OrderLogConsts.ORDER_LOG_TYPE_ASSIGN_BACK)).collect(Collectors.toList());
        }

        // 用户申请已取消日志
        Integer waitCancelStatus = GlobalConsts.NO;
        Date cancelApplyTime = null;
        CancelApplyResultBO waitCancelInfo = cancelApplyBService.getWaitCancelInfo(orderWork.getOrderId(), orderWork.getWorkId());
        if (Objects.equals(waitCancelInfo.getUserWaitCancelStatus(), GlobalConsts.YES)) {
            waitCancelStatus = GlobalConsts.YES;
            cancelApplyTime = waitCancelInfo.getCanelApplyTime();
        }else {
            OrderWorkTrack orderWorkTrack = workTrackBService.getUserWaitCancelTrack(orderWork);
            waitCancelStatus = orderWorkTrack == null ? GlobalConsts.NO : GlobalConsts.YES;
            cancelApplyTime = orderWorkTrack == null ? null : orderWorkTrack.getCreateTime();
        }


        // 取消状态
        List<Integer> resultStatusList = Lists.newArrayList(OrderStatusConsts.WORK_RESULT_FAIL, OrderStatusConsts.WORK_RESULT_DISCARD);
        // 未完成  取消/失败
        boolean resultStatusSupport = (resultStatusList.contains(orderWork.getResultStatus()) && orderWork.getCompleteTime() == null) ||
                Objects.equals(waitCancelStatus,GlobalConsts.YES);
        // 退款中 退款成功
        boolean isReviewStatus = Objects.equals(orderWork.getRefundReviewStatus(), OrderConsts.REVIEW_STATUS_DOING) || Objects.equals(orderWork.getRefundReviewStatus(), OrderConsts.REVIEW_STATUS_SUCCESS);
        // 存在退款单
        boolean isExistRefundOrder = NumberUtil.isNotNullOrZero(orderWork.getRefundTargetWorkId());

        // 订单未完成
        boolean isStatus = orderWork.getStatus() < OrderStatusConsts.WORK_STATUS_COMPLETE;
        if (!resultStatusSupport && !isReviewStatus && isStatus) {
            // 组装全量待-- 虚拟进程
            if (orderWork.getStatus() <= OrderStatusConsts.WORK_STATUS_DISTRIBUTE) {
                if (prepaying) {
                    OrderWorkDetailSpoolDRO prepayingDTO = new OrderWorkDetailSpoolDRO();
                    prepayingDTO.setLogTypeName("待支付");
                    prepayingDTO.setLogRemark("待支付");
                    contactList.add(prepayingDTO);
                } else {
                    List<OrderNodeSpoolConsts.OrderNodeSpoolDRO> copyList = OrderNodeSpoolConsts.getInstance().getNodeSpoolList();
                    List<OrderWorkDetailSpoolDRO> copyListDTO = BeanMapper.mapList(copyList, OrderWorkDetailSpoolDRO.class);
                    contactList.addAll(copyListDTO);
                }
            } else if (Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_TAKE)) {
                int index = 1;
                boolean isExistContactUser = contactList.stream().anyMatch(ite -> ite.getLogType().equals(OrderLogConsts.ORDER_LOG_TYPE_CONTACT_USER));
                if (isExistContactUser) {
                    index = 2;
                }
                List<OrderNodeSpoolConsts.OrderNodeSpoolDRO> copyList = OrderNodeSpoolConsts.getInstance().getNodeSpoolList().subList(index, OrderNodeSpoolConsts.getInstance().getNodeSpoolList().size());
                List<OrderWorkDetailSpoolDRO> copyListDTO = BeanMapper.mapList(copyList, OrderWorkDetailSpoolDRO.class);
                contactList.addAll(copyListDTO);
            } else if (Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_VISIT)) {
                List<OrderNodeSpoolConsts.OrderNodeSpoolDRO> copyList = OrderNodeSpoolConsts.getInstance().getNodeSpoolList().subList(3, OrderNodeSpoolConsts.getInstance().getNodeSpoolList().size());
                List<OrderWorkDetailSpoolDRO> copyListDTO = BeanMapper.mapList(copyList, OrderWorkDetailSpoolDRO.class);
                contactList.addAll(copyListDTO);
            }
        }


        if (isComplete && !resultStatusSupport) {
            OrderComment comment = orderCommentService.findCommentByKey(orderId);
            if (orderWarranty != null && (Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_ZMN) || Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_CNHB))) {
                OrderWorkDetailSpoolDRO orderWorkDetailSpool = new OrderWorkDetailSpoolDRO();
                orderWorkDetailSpool.setOperateTime(orderWork.getCompleteTime());
                orderWorkDetailSpool.setLogType(OrderLogConsts.ORDER_LOG_TYPE_WARRANTY);
                orderWorkDetailSpool.setLogTypeName("已发保修卡");
                orderWorkDetailSpool.setLogRemark("请主人进入“我的->保修卡”页面查收保修卡");
                contactList.add(orderWorkDetailSpool);
            }

            if (comment != null) {
                OrderWorkDetailSpoolDRO orderWorkDetailSpool = new OrderWorkDetailSpoolDRO();
                orderWorkDetailSpool.setOperateTime(comment.getCreateTime());
                orderWorkDetailSpool.setLogType(OrderLogConsts.ORDER_LOG_TYPE_COMMENT);
                orderWorkDetailSpool.setLogTypeName("已评价");
                orderWorkDetailSpool.setLogRemark(comment.getContent());
                if (CollectionUtil.isNotNullOrEmpty(comment.getDetailList())) {
                    List<String> commenttags = comment.getDetailList()
                            .stream()
                            .map(OrderCommentDetail::getMapName)
                            .collect(Collectors.toList());
                    orderWorkDetailSpool.setLogRemark(String.format("%s%s", String.join(",", commenttags), Optional.ofNullable(comment.getContent()).orElse("")));
                }
                orderWorkDetailSpool.setCommentScore(comment.getScore());
                if (Objects.equals(comment.getType(), OrderConsts.COMMENT_TYPE_DEFAULT)) {
                    orderWorkDetailSpool.setCommentScore(null);
                    orderWorkDetailSpool.setLogRemark("主人未及时点评，系统默默给了五星好评");
                }
                contactList.add(orderWorkDetailSpool);

                if (Objects.nonNull(comment.getAppendTime())) {
                    OrderWorkDetailSpoolDRO orderWorkDetailSpoolAppendComment = new OrderWorkDetailSpoolDRO();
                    orderWorkDetailSpoolAppendComment.setOperateTime(comment.getAppendTime());
                    orderWorkDetailSpoolAppendComment.setLogType(OrderLogConsts.ORDER_LOG_TYPE_COMMENT_APPEND);
                    orderWorkDetailSpoolAppendComment.setLogTypeName("已追评");
                    orderWorkDetailSpoolAppendComment.setLogRemark(comment.getAppendContent());
                    contactList.add(orderWorkDetailSpoolAppendComment);
                }
            }

            if (comment == null && !isExistRefundOrder) {
                OrderWorkDetailSpoolDRO orderWorkDetailSpool = new OrderWorkDetailSpoolDRO();
                orderWorkDetailSpool.setLogTypeName("待评价");
                orderWorkDetailSpool.setLogRemark("服务已完成，期待主人的评价");
                contactList.add(orderWorkDetailSpool);
            }
        }

        // 原单存在退款单 组装退款节点
        if (isExistRefundOrder) {
            OrderWorkDetailSpoolDRO orderWorkDetailSpool1 = new OrderWorkDetailSpoolDRO();
            // 原单存在返修单 进行补全数据
            OrderWorkQuery query = new OrderWorkQuery();
            query.setOrderId(orderId);
            query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_REFUND));
            query.setIncludes(Arrays.asList("lastRefundAmountTime"));
            List<EsOrderWork> esOrderWorkList = orderWorkListBService.listPageOrderWorkByQuery(query);
            if (CollectionUtil.isNotNullOrEmpty(esOrderWorkList)) {
                orderWorkDetailSpool1.setOperateTime(esOrderWorkList.get(0).getLastRefundAmountTime());
            }
            orderWorkDetailSpool1.setLogType(3000);// 临时设值
            orderWorkDetailSpool1.setLogTypeName("用户退款成功");
            orderWorkDetailSpool1.setLogRemark("退款受理成功，将尽快退回到主人的支付账户，请主人注意查收，期待再次为主人服务");
            contactList.add(orderWorkDetailSpool1);
        }

        // 预约金订单，发起退款，取消审核失败后，不展示取消节点，取消节点，显示为退款失败
        if (hasPrepay && !Objects.equals(orderWork.getPrepayStatus(), PayConsts.PAY_STATUS_ING) && orderWork.getPrepayTime() != null && !resultStatusList.contains(orderWork.getResultStatus())) {
            if (orderWork.getRefundApplyTime() != null && Objects.equals(orderWork.getRefundReviewStatus(), OrderConsts.REVIEW_STATUS_FAIL)) {
                contactList.forEach(item -> {
                    if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_CANCEL, item.getLogType())) {
                        item.setLogTypeName("用户退款取消");
                        item.setLogRemark("主人的退款已经取消，如有疑问请与小啄联系或拨打400-023-8888");
                    }
                });
            }
        }

        // 过滤隐藏派单节点
        List<Integer> nodes = Lists.newArrayList(OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE,
                OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE_BACK,
                OrderLogConsts.ORDER_LOG_TYPE_ASSIGN_BACK,
                OrderLogConsts.ORDER_LOG_TYPE_CONTACT_USER,
                OrderLogConsts.ORDER_LOG_TYPE_REFUND_RESULT,
                OrderLogConsts.ORDER_LOG_TYPE_VISIT);
        List<OrderWorkDetailSpoolDRO> newList = contactList.stream().filter(item -> !nodes.contains(item.getLogType())).collect(Collectors.toList());

        newList.forEach(e -> {
            e.setOrderId(orderWork.getOrderId());
            e.setWorkId(orderWork.getWorkId());
        });

        if (cancelApplyTime != null && Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            OrderWorkDetailSpoolDRO cancelLog = new OrderWorkDetailSpoolDRO();
            cancelLog.setLogRemark("取消成功，小啄将再接再厉，随时等候主人的召唤，任何问题请联系小啄或拨打400-023-8888");
            cancelLog.setOperateTime(cancelApplyTime);
            cancelLog.setOrderId(orderId);
            cancelLog.setWorkId(workId);
            cancelLog.setLogType(OrderLogConsts.ORDER_LOG_TYPE_CANCEL);
            cancelLog.setLogTypeName("订单已取消");
            newList.add(cancelLog);
        }

        return newList;
    }

    /**
     * 处理节点
     * @param list      原节点
     * @param orderId   订单id
     * @param workId    工单id
     * @param orderWork 工单
     * @return
     */
    private List<OrderWorkDetailSpoolDRO> handleNode(List<OrderWorkDetailSpoolDRO> list, Long orderId, Long workId, OrderWork orderWork) {
        List<OrderWorkDetailSpoolDRO> listCopy = Lists.newLinkedList();

        // 是否有过派单操作
        boolean isExistDistribute = list.stream().anyMatch(item -> item.getLogType().equals(OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE));

        int count = 0;
        for (int i = 0, len = list.size(); i < len; i++) {
            OrderWorkDetailSpoolDRO item = list.get(i);
            // 复制节点
            listCopy.add(item);
            switch (item.getLogType()) {
                case OrderLogConsts.ORDER_LOG_TYPE_TAKE:
                    // 获取下一节点时 防止下标越界
                    if (i == list.size() - 1) {
                        break;
                    }
                    OrderWorkDetailSpoolDRO nextObj1 = list.get(i + 1);
                    // 接单的下一节点是 "联系用户节点" 取第一个联系用户信息 进行组装
                    if (Objects.equals(nextObj1.getLogType(), OrderLogConsts.ORDER_LOG_TYPE_CONTACT_USER)) {
                        OrderWorkDetailSpoolDRO orderWorkDetailSpool1 = new OrderWorkDetailSpoolDRO();
                        orderWorkDetailSpool1.setOperateTime(nextObj1.getOperateTime());
                        orderWorkDetailSpool1.setLogType(2000);// 临时设值
                        orderWorkDetailSpool1.setLogTypeName("服务时间已确认");
                        orderWorkDetailSpool1.setLogRemark("工程师将尽快上门，请主人耐心等待");
                        listCopy.add(orderWorkDetailSpool1);
                    }
                    // 师傅上门之前 ，接单下一节点不存在 联系用户节点，自动补全联系用户节点
                    else if (Objects.equals(nextObj1.getLogType(), OrderLogConsts.ORDER_LOG_TYPE_VISIT)) {
                        OrderWorkDetailSpoolDRO orderWorkDetailSpool1 = new OrderWorkDetailSpoolDRO();
                        orderWorkDetailSpool1.setOperateTime(nextObj1.getOperateTime());
                        orderWorkDetailSpool1.setLogType(2000);// 临时设值
                        orderWorkDetailSpool1.setLogTypeName("服务时间已确认");
                        orderWorkDetailSpool1.setLogRemark("工程师将尽快上门，请主人耐心等待");
                        listCopy.add(orderWorkDetailSpool1);
                    }
                    break;
                // 处理上门重复
                case OrderLogConsts.ORDER_LOG_TYPE_VISIT:
                    // 获取下一节点时 防止下标越界
                    if (i == list.size() - 1) {
                        OrderWorkDetailSpoolDRO orderWorkDetailSpool1 = new OrderWorkDetailSpoolDRO();
                        orderWorkDetailSpool1.setOperateTime(item.getOperateTime());
                        orderWorkDetailSpool1.setLogType(4000);// 临时设值
                        orderWorkDetailSpool1.setLogTypeName(item.getLogTypeName());
                        orderWorkDetailSpool1.setLogRemark(item.getLogRemark());
                        listCopy.add(orderWorkDetailSpool1);
                        break;
                    }
                    OrderWorkDetailSpoolDRO nextObj = list.get(i + 1);
                    if (!Objects.equals(nextObj.getLogType(), OrderLogConsts.ORDER_LOG_TYPE_VISIT)) {
                        OrderWorkDetailSpoolDRO orderWorkDetailSpool1 = new OrderWorkDetailSpoolDRO();
                        orderWorkDetailSpool1.setOperateTime(item.getOperateTime());
                        orderWorkDetailSpool1.setLogType(4000);// 临时设值
                        orderWorkDetailSpool1.setLogTypeName(item.getLogTypeName());
                        orderWorkDetailSpool1.setLogRemark(item.getLogRemark());
                        listCopy.add(orderWorkDetailSpool1);
                    }
                    break;
                case OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE:
                    count++;
                    if (count > 1) {
                        // 从第二次派单开始 转换派单节点为重新派单节点
                        OrderWorkDetailSpoolDRO orderWorkDetailSpool1 = new OrderWorkDetailSpoolDRO();
                        orderWorkDetailSpool1.setOperateTime(item.getOperateTime());
                        orderWorkDetailSpool1.setLogType(1000);// 临时设值
                        orderWorkDetailSpool1.setLogTypeName("订单已重新派单");
                        orderWorkDetailSpool1.setLogRemark("订单交给" + item.getMasterName() + "，小啄将督促工程师尽快接单");
                        listCopy.add(orderWorkDetailSpool1);
                    }
                    break;
                case OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE_BACK:
                case OrderLogConsts.ORDER_LOG_TYPE_ASSIGN_BACK:
                    // 派单/分单撤回且未进行再次派单，节点为最后一个节点，进行组装 即重新派单。。。 虚拟节点
                    if (i == list.size() - 1) {
                        if (isExistDistribute) {
                            OrderWorkDetailSpoolDRO orderWorkDetailSpool = new OrderWorkDetailSpoolDRO();
                            orderWorkDetailSpool.setLogTypeName("订单已改派");
                            orderWorkDetailSpool.setLogRemark("改派成功，将尽快为主人派单");
                            listCopy.add(orderWorkDetailSpool);
                        }
                    }
                    break;
                case OrderLogConsts.ORDER_LOG_TYPE_REFUND_RESULT:
                    // 退款成功节点为最后一个节点时进行重新组装 ，防节点重复
                    if (i == list.size() - 1) {
                        OrderWorkDetailSpoolDRO orderWorkDetailSpool = new OrderWorkDetailSpoolDRO();
                        orderWorkDetailSpool.setOperateTime(item.getOperateTime());
                        orderWorkDetailSpool.setLogType(3000);// 临时设值
                        orderWorkDetailSpool.setLogTypeName(item.getLogTypeName());
                        orderWorkDetailSpool.setLogRemark(item.getLogRemark());
                        listCopy.add(orderWorkDetailSpool);
                    }
                    break;
                default:
                    break;
            }
        }
        return listCopy;
    }

    /**
     * 处理多次上门节点
     * @param list      原节点
     * @param orderWork 工单
     * @return
     */
    private List<OrderWorkDetailSpoolDRO> handleMultipleVisitNode(List<OrderWorkDetailSpoolDRO> list, OrderWork orderWork) {

        // 把多次上门日志过滤掉，重新设置
        list  = list.stream()
                .filter(e -> !Objects.equals(e.getLogType(), OrderLogConsts.ORDER_LOG_TYPE_APPLY_MULTIPLE_VISIT))
                .collect(Collectors.toList());

        List<OrderVisit> orderVisitList = orderVisitService.listOrderVisitByOrderIdList(Lists.newArrayList(orderWork.getOrderId()));
        if (CollectionUtil.isNullOrEmpty(orderVisitList)){
            return list;
        }

        // 过滤已取消的节点
        orderVisitList = orderVisitList.stream()
                .filter(e -> !Objects.equals(e.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_CANCEL))
                .collect(Collectors.toList());

        if (CollectionUtil.isNullOrEmpty(orderVisitList)){
            return list;
        }

        String format = "MM-dd HH:mm";

        for (OrderVisit orderVisit : orderVisitList) {
            OrderWorkDetailSpoolDRO applyVisit = new OrderWorkDetailSpoolDRO();
            applyVisit.setOrderId(orderWork.getOrderId());
            applyVisit.setWorkId(orderWork.getWorkId());
            applyVisit.setLogType(OrderLogConsts.ORDER_LOG_TYPE_APPLY_MULTIPLE_VISIT);
            applyVisit.setLogTypeName(OrderNodeSpoolConsts.getOperateTypeName(OrderLogConsts.ORDER_LOG_TYPE_APPLY_MULTIPLE_VISIT));
            applyVisit.setLogRemark("工程师将在" + DateUtil.dateFormatToString(orderVisit.getExpectVisitTime(), format) + "再次上门，请主人耐心等待");
            applyVisit.setOperateTime(orderVisit.getCreateTime());
            list.add(applyVisit);

            // 如果已上门展示再次上门节点
            if (Objects.equals(orderVisit.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_VISIT)) {
                OrderWorkDetailSpoolDRO againVisit = new OrderWorkDetailSpoolDRO();
                againVisit.setOrderId(orderWork.getOrderId());
                againVisit.setWorkId(orderWork.getWorkId());
                againVisit.setLogType(OrderLogConsts.ORDER_LOG_TYPE_AGAIN_VISIT);
                againVisit.setLogTypeName(OrderNodeSpoolConsts.getOperateTypeName(OrderLogConsts.ORDER_LOG_TYPE_AGAIN_VISIT));
                againVisit.setLogRemark("为保障主人权益，订单如需报价请亲自使用啄木鸟维修计价器");
                againVisit.setOperateTime(orderVisit.getActualVisitTime());
                list.add(againVisit);
            }
        }

        list = list.stream().sorted(Comparator.comparing(OrderWorkDetailSpoolDRO::getOperateTime)).collect(Collectors.toList());

        return list;
    }

    /**
     * 处理退款重复日志节点
     *
     * @param list
     * @return
     */
    private void handleRepeatNode(List<OrderWorkDetailSpoolDRO> list) {
        for (int j = 0, len = list.size(); j < len; j++) {
            OrderWorkDetailSpoolDRO item = list.get(j);
            switch (item.getLogType()) {
                case OrderLogConsts.ORDER_LOG_TYPE_REFUND_RESULT:
                    // 退款成功节点为最后一个节点时进行重新组装 ，防节点重复
                    if (list.size() - 1 == j) {
                        OrderWorkDetailSpoolDRO orderWorkDetailSpool = new OrderWorkDetailSpoolDRO();
                        orderWorkDetailSpool.setOperateTime(item.getOperateTime());
                        orderWorkDetailSpool.setLogTypeName(item.getLogTypeName());
                        orderWorkDetailSpool.setLogRemark(item.getLogRemark());
                        orderWorkDetailSpool.setLogType(3000);// 临时设值
                        list.add(orderWorkDetailSpool);
                    }
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 获取师傅信息
     *
     * @param masterId
     * @return
     */
    private ForeignEngineerDetailInfoDRO getMaterInfo(Integer masterId) {
        if (NumberUtil.isNullOrZero(masterId)) {
            return null;
        }
        // todo fubiao
        log.info("getMaterInfo#getEngineerDetailById 入参 [{}]",masterId);
        ResponseDTO<ForeignEngineerDetailInfoDRO> resp = engineerListRemoteService.getEngineerDetailById(masterId);
        log.info("getMaterInfo#getEngineerDetailById 出参 [{}]", JSON.toJSONString(resp));
        if (resp.isSuccess() && Objects.nonNull(resp.getData())) {
            return resp.getData();
        }
        return null;
    }

    @Override
    public ResponseDTO<List<OrderWorkSpoolDRO>> listFirstOrderNodeSpoolByUserIds(Set<Long> userIds, Integer plat) {
        log.info("ZsNormalOrderNodeSpoolRemoteServiceImpl.listFirstOrderNodeSpoolByUserIds userIds={},plat={}", userIds, plat);

        if (userIds.isEmpty()) {
            return ResponseDTO.fail("用户Id不能为空");
        }

        OrderWorkQuery query = new OrderWorkQuery();
        query.setUserIdList(Lists.newArrayList(userIds));
        query.setPlatWork(plat);
        query.setWorkType(Lists.newArrayList(OrderConsts.ORDER_TYPE_REWORK, OrderConsts.ORDER_TYPE_NEW));
        // 提交订单、确认订单、成功派单、师傅接单 -- 进行中
        query.setWorkResultStatus(OrderStatusConsts.WORK_RESULT_DOING);
        query.setWorkStatus(Lists.newArrayList(
                OrderStatusConsts.WORK_STATUS_INPUT,
                OrderStatusConsts.WORK_STATUS_CONFIRM,
                OrderStatusConsts.WORK_STATUS_ASSIGN,
                OrderStatusConsts.WORK_STATUS_DISTRIBUTE,
                OrderStatusConsts.WORK_STATUS_TAKE));
        query.setNotWaitCancel(GlobalConsts.YES);
        query.setNotPrepayStatus(PayConsts.PAY_STATUS_ING);
        query.setIncludes(Arrays.asList("orderId"));
        List<EsOrderWork> esOrderWorkList = orderWorkListBService.listPageOrderWorkByQuery(query);

        if (CollectionUtils.isEmpty(esOrderWorkList)) {
            return ResponseDTO.success();
        }

        log.info("esOrderWorkList.size={}", esOrderWorkList.size());

        // 所有用户的订单Id
        Set<Long> orderIdList = esOrderWorkList.stream().map(EsOrderWork::getOrderId).collect(Collectors.toSet());
        List<Long> orderList = Lists.newArrayList(orderIdList);
        List<Long> orderListSub;
        if (orderIdList.size() > 5) {
            orderListSub = orderList.subList(0, 5);
        } else {
            orderListSub = orderList;
        }
        // 用户订单集合
        List<OrderWork> orderWorkList = orderWorkService.listEsOrderWorkByOrderIdList(orderListSub);
        Map<Long, OrderWork> orderWorkMap = orderWorkList.stream().collect(Collectors.toMap(OrderWork::getWorkId, orderWork -> orderWork));

        List<OrderWorkSpoolDRO> orderWorkSpoolList = Lists.newArrayListWithCapacity(orderIdList.size());
        for (Long item : orderIdList) {
            OrderWork orderWork = orderWorkMap.get(item);
            if (Objects.isNull(orderWork)) {
                continue;
            }

            // 获取单个订单的生命周期信息
            List<OrderWorkDetailSpoolDRO> listOrderSpool = listOrderNodeSpoolList(orderWork, item, item);
            // 过滤待节点，取最新一个时间节点
            List<OrderWorkDetailSpoolDRO> detailSpoolList = listOrderSpool.stream().filter(it -> it.getOperateTime() != null).collect(Collectors.toList());
            if (detailSpoolList.isEmpty()) {
                continue;
            }
            // 获取最新一个节点
            OrderWorkDetailSpoolDRO lastNewDetailSpool = detailSpoolList.get(detailSpoolList.size() - 1);
            OrderWorkSpoolDRO OrderWorkSpoolDRO = BeanMapper.map(lastNewDetailSpool, OrderWorkSpoolDRO.class);
            OrderWorkSpoolDRO.setShowProductId(orderWork.getShowProductId());
            orderWorkSpoolList.add(OrderWorkSpoolDRO);
        }

        return ResponseDTO.success(orderWorkSpoolList);
    }


}